/**
 *******************************************************************************
 * @file  basic.h
 * @brief This file contains all the functions prototypes of the basic driver.
 @verbatim
   Change Logs:
   Date             Author          Notes
   2019-06-26       Yangjp          First version
 @endverbatim
 *******************************************************************************
 * Copyright (C) 2016, Huada Semiconductor Co., Ltd. All rights reserved.
 *
 * This software is owned and published by:
 * Huada Semiconductor Co., Ltd. ("HDSC").
 *
 * BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
 * BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
 *
 * This software contains source code for use with HDSC
 * components. This software is licensed by HDSC to be adapted only
 * for use in systems utilizing HDSC components. HDSC shall not be
 * responsible for misuse or illegal use of this software for devices not
 * supported herein. HDSC is providing this software "AS IS" and will
 * not be responsible for issues arising from incorrect user implementation
 * of the software.
 *
 * Disclaimer:
 * HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
 * REGARDING THE SOFTWARE (INCLUDING ANY ACCOMPANYING WRITTEN MATERIALS),
 * ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
 * WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
 * WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
 * WARRANTY OF NONINFRINGEMENT.
 * HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
 * NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
 * LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
 * LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
 * INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
 * SAVINGS OR PROFITS,
 * EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
 * YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
 * INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
 * FROM, THE SOFTWARE.
 *
 * This software may be replicated in part or whole for the licensed use,
 * with the restriction that this Disclaimer and Copyright notice must be
 * included with each copy of this software, whether used in part or whole,
 * at all times.
 *******************************************************************************
 */
#ifndef __BASIC_H__
#define __BASIC_H__

/* C binding of definitions if building with C++ compiler */
#ifdef __cplusplus
extern "C"
{
#endif

/*******************************************************************************
 * Include files
 ******************************************************************************/
#include "hc32_common.h"

/**
 * @addtogroup HC32_Boot
 * @{
 */

/**
 * @addtogroup Basic
 * @{
 */

/*******************************************************************************
 * Global type definitions ('typedef')
 ******************************************************************************/

/*******************************************************************************
 * Global pre-processor symbols/macros ('#define')
 ******************************************************************************/
/**
 * @defgroup Basic_Global_Macros Basic Global Macros
 * @{
 */

/* Tick reload value */
#define TICK_RELOAD_VALUE               (0xFFFFFFFFUL)

/* System clock source definition */
#define CLK_SOURCE_HRC                  (0U)
#define CLK_SOURCE_XTAL                 (1U)

#define SYSTEM_CLOCK_SOURCE             (CLK_SOURCE_HRC)

/* LED definition */
#if defined(HC32F460) || defined(HC32F4A0)
    #if defined(HC32F460)
        #define PORT_PODR_POUT06        (0x0040U)
        #define PORT_PODR_POUT09        (0x0200U)

        #define LED_R_EN_PORT           (M4_PORT->POERE)
        #define LED_R_PORT              (M4_PORT->PODRE)    //PE06
        #define LED_R_PIN               (PORT_PODR_POUT06)

        #define LED_B_EN_PORT           (M4_PORT->POERB)
        #define LED_B_PORT              (M4_PORT->PODRB)    //PB09
        #define LED_B_PIN               (PORT_PODR_POUT09)
    #elif defined(HC32F4A0)
        #define LED_G1_EN_PORT          (M4_GPIO->POERB)
        #define LED_G1_PORT             (M4_GPIO->PODRB)    //PB11
        #define LED_G1_PIN              (GPIO_PODRB_POUT11)

        #define LED_G2_EN_PORT          (M4_GPIO->POERC)
        #define LED_G2_PORT             (M4_GPIO->PODRC)    //PC09
        #define LED_G2_PIN              (GPIO_PODRC_POUT09)
    #endif

    #define LED_ON(Port, Pin)           SET_BIT(Port, Pin)
    #define LED_OFF(Port, Pin)          CLEAR_BIT(Port, Pin)
#elif defined(HC32F120) || defined(HC32M120) || defined(HC32M423) || defined(HC32F160)
    #if defined(HC32F120)
        #define LED_R_EN_PORT           (M0P_PORT->POER2)
        #define LED_R_PORT              (M0P_PORT->PODR2)   //P25
        #define LED_R_PIN               (PORT_PODR2_POUT5)

        #define LED_B_EN_PORT           (M0P_PORT->POER2)
        #define LED_B_PORT              (M0P_PORT->PODR2)   //P27
        #define LED_B_PIN               (PORT_PODR2_POUT7)
    #elif defined(HC32M120)
        #define LED_R_EN_PORT           (M0P_PORT->POER12)
        #define LED_R_PORT              (M0P_PORT->PODR12)  //P120
        #define LED_R_PIN               (PORT_PODR12_POUT0)

        #define LED_B_EN_PORT           (M0P_PORT->POER3)
        #define LED_B_PORT              (M0P_PORT->PODR3)   //P31
        #define LED_B_PIN               (PORT_PODR3_POUT1)
    #elif defined(HC32M423)
        #define LED_R_EN_PORT           (CM_GPIO->POERA)
        #define LED_R_PORT              (CM_GPIO->PODRA)    //PA4
        #define LED_R_PIN               (GPIO_PODR_POUT4)

        #define LED_B_EN_PORT           (CM_GPIO->POER1)
        #define LED_B_PORT              (CM_GPIO->PODR1)    //P10
        #define LED_B_PIN               (GPIO_PODR_POUT0)
    #elif defined(HC32F160)
        #define LED_R_EN_PORT           (CM_GPIO->POER5)
        #define LED_R_PORT              (CM_GPIO->PODR5)    //P52
        #define LED_R_PIN               (GPIO_PODR_POUT2)

        #define LED_B_EN_PORT           (CM_GPIO->POER5)
        #define LED_B_PORT              (CM_GPIO->PODR5)    //P54
        #define LED_B_PIN               (GPIO_PODR_POUT4)
    #endif

    #define LED_ON(Port, Pin)           CLEAR_BIT(Port, Pin)
    #define LED_OFF(Port, Pin)          SET_BIT(Port, Pin)
#else
    #error "Please select first the target HC32xxxx device used"
#endif

/* System basic definition */
#if defined(HC32F460) || defined(HC32F4A0)
    #define VECTOR_TABLE_STEP           (0x400UL)
    #define CRC_BASE                    (M4_CRC)

    #define EFM_UNLOCK()                WRITE_REG(M4_EFM->FAPRT, 0x0123UL); \
                                        WRITE_REG(M4_EFM->FAPRT, 0x3210UL)
    #define EFM_LOCK()                  WRITE_REG(M4_EFM->FAPRT, 0UL)

    #define SRAM_WTCR_UNLOCK()          WRITE_REG(M4_SRAMC->WTPR, 0x77U)
    #define SRAM_WTCR_LOCK()            WRITE_REG(M4_SRAMC->WTPR, 0x76U)

    #if defined(HC32F460)
        #define MSTP_FCG0_CRC           (0x00800000UL)
        #define CRC_CR_SEL              (0x00000002UL)

        #define CLK_UNLOCK()            WRITE_REG(M4_SYSREG->PWR_FPRC, 0xA501U)
        #define CLK_LOCK()              WRITE_REG(M4_SYSREG->PWR_FPRC, 0xA500U)

        #define GPIO_UNLOCK()           WRITE_REG(M4_PORT->PWPR, 0xA501U)
        #define GPIO_LOCK()             WRITE_REG(M4_PORT->PWPR, 0xA500U)

        #define FCG0_UNLOCK()           WRITE_REG(M4_MSTP->FCG0PC, 0xA5A50001UL)
        #define FCG0_LOCK()             WRITE_REG(M4_MSTP->FCG0PC, 0xA5A50000UL)
    #elif defined(HC32F4A0)
        #define CLK_UNLOCK()            WRITE_REG(M4_PWC->FPRC, 0xA501U)
        #define CLK_LOCK()              WRITE_REG(M4_PWC->FPRC, 0xA500U)

        #define GPIO_UNLOCK()           WRITE_REG(M4_GPIO->PWPR, 0xA501U)
        #define GPIO_LOCK()             WRITE_REG(M4_GPIO->PWPR, 0xA500U)

        #define FCG0_UNLOCK()           WRITE_REG(M4_PWC->FCG0PC, 0xA5A50001UL)
        #define FCG0_LOCK()             WRITE_REG(M4_PWC->FCG0PC, 0xA5A50000UL)

        #define EFM_FWMC_UNLOCK()       WRITE_REG(M4_EFM->KEY1, 0x01234567UL); \
                                        WRITE_REG(M4_EFM->KEY1, 0xFEDCBA98UL)
        #define EFM_FWMC_LOCK()         SET_BIT(M4_EFM->FWMC, 0x00010000UL)

        #define EFM_SECTOR_UNLOCK()     WRITE_REG(M4_EFM->F0NWPRT0, 0xFFFFFFFFUL); \
                                        WRITE_REG(M4_EFM->F0NWPRT1, 0xFFFFFFFFUL); \
                                        WRITE_REG(M4_EFM->F0NWPRT2, 0xFFFFFFFFUL); \
                                        WRITE_REG(M4_EFM->F0NWPRT3, 0xFFFFFFFFUL); \
                                        WRITE_REG(M4_EFM->F1NWPRT0, 0xFFFFFFFFUL); \
                                        WRITE_REG(M4_EFM->F1NWPRT1, 0xFFFFFFFFUL); \
                                        WRITE_REG(M4_EFM->F1NWPRT2, 0xFFFFFFFFUL); \
                                        WRITE_REG(M4_EFM->F1NWPRT3, 0xFFFFFFFFUL)
        #define EFM_SECTOR_LOCK()       WRITE_REG(M4_EFM->F0NWPRT0, 0UL); \
                                        WRITE_REG(M4_EFM->F0NWPRT1, 0UL); \
                                        WRITE_REG(M4_EFM->F0NWPRT2, 0UL); \
                                        WRITE_REG(M4_EFM->F0NWPRT3, 0UL); \
                                        WRITE_REG(M4_EFM->F1NWPRT0, 0UL); \
                                        WRITE_REG(M4_EFM->F1NWPRT1, 0UL); \
                                        WRITE_REG(M4_EFM->F1NWPRT2, 0UL); \
                                        WRITE_REG(M4_EFM->F1NWPRT3, 0UL)
    #endif
#elif defined(HC32F120) || defined(HC32M120)
    #define VECTOR_TABLE_STEP           (0x100UL)
    #define CRC_BASE                    (M0P_CRC)

    #define CLK_UNLOCK()                WRITE_REG(M0P_PWC->FPRC, 0xA501U)
    #define CLK_LOCK()                  WRITE_REG(M0P_PWC->FPRC, 0xA500U)

    #define GPIO_UNLOCK()               WRITE_REG(M0P_PORT->PWPR, 0xA501U)
    #define GPIO_LOCK()                 WRITE_REG(M0P_PORT->PWPR, 0xA500U)

    #define EFM_UNLOCK()                WRITE_REG(M0P_EFM->FAPRT, 0x0123UL); \
                                        WRITE_REG(M0P_EFM->FAPRT, 0x3210UL)
    #define EFM_LOCK()                  WRITE_REG(M0P_EFM->FAPRT, 0UL)
#elif defined(HC32F160)
    #define VECTOR_TABLE_STEP           (0x100UL)
    #define CRC_BASE                    (CM_CRC)

    #define CLK_UNLOCK()                WRITE_REG(CM_PWC->FPRC, 0xA501U)
    #define CLK_LOCK()                  WRITE_REG(CM_PWC->FPRC, 0xA500U)

    #define GPIO_UNLOCK()               WRITE_REG(CM_GPIO->PWPR, 0xA501U)
    #define GPIO_LOCK()                 WRITE_REG(CM_GPIO->PWPR, 0xA500U)

    #define EFM_UNLOCK()                WRITE_REG(CM_EFM->FAPRT, 0x0123UL); \
                                        WRITE_REG(CM_EFM->FAPRT, 0x3210UL)
    #define EFM_LOCK()                  WRITE_REG(CM_EFM->FAPRT, 0xABCDUL)

    #define INTC_UNLOCK()               WRITE_REG(CM_INTC->FPRCR, 0xA5U)
    #define INTC_LOCK()                 WRITE_REG(CM_INTC->FPRCR, 0x00U)
#elif defined(HC32M423)
    #define VECTOR_TABLE_STEP           (0x200UL)
    #define CRC_BASE                    (CM_CRC)

    #define CLK_UNLOCK()                WRITE_REG(CM_PWC->FPRC, 0xA501U)
    #define CLK_LOCK()                  WRITE_REG(CM_PWC->FPRC, 0xA500U)

    #define GPIO_UNLOCK()               WRITE_REG(CM_GPIO->PWPR, 0xA501U)
    #define GPIO_LOCK()                 WRITE_REG(CM_GPIO->PWPR, 0xA500U)

    #define EFM_UNLOCK()                WRITE_REG(CM_EFM->FAPRT, 0x0123UL); \
                                        WRITE_REG(CM_EFM->FAPRT, 0x3210UL)
    #define EFM_LOCK()                  WRITE_REG(CM_EFM->FAPRT, 0UL)
#else
    #error "Please select first the target HC32xxxx device used"
#endif

/**
 * @}
 */

/*******************************************************************************
 * Global variable definitions ('extern')
 ******************************************************************************/

/*******************************************************************************
  Global function prototypes (definition in C source)
 ******************************************************************************/
/**
 * @addtogroup Basic_Global_Functions
 * @{
 */

void SystemClock_Init(void);
void SystemClock_DeInit(void);

void SysTick_Init(void);
void SysTick_DeInit(void);
uint32_t SysTick_GetTick(void);
void SysTick_Delay(uint32_t u32DelayMs);

void LED_Init(void);
void LED_DeInit(void);

void CRC_Init(void);
void CRC_DeInit(void);
uint16_t Calculate_CRC16(const uint8_t* pu8Data, uint32_t u32Size);
en_result_t FLASH_GetCrcValue(uint32_t u32Addr, uint32_t u32ByteLength, uint16_t *u16CrcVal);

/**
 * @}
 */

/**
 * @}
 */

/**
 * @}
 */

#ifdef __cplusplus
}
#endif

#endif /* __BASIC_H__ */

/*******************************************************************************
 * EOF (not truncated)
 ******************************************************************************/
